package IC.SymbolTable;

import IC.SemanticCheckes.SemanticError;
import IC.AST.*;
import java.util.*;

public class GlobalSymbolTable extends SymbolTable {
	
	public GlobalSymbolTable(String icFileName){
		this.InitSymbol(null);
		this.classSymbols = new HashMap<String, ClassSymbol>();
		this.classSymbolTables = new HashMap<String, ClassSymbolTable>();
		this.icFileName = icFileName;
	}
	
	public ClassSymbol getClassSymbol(String name){
		return classSymbols.get(name);
	}

	public ClassSymbolTable getClassSymbolTable(String name){
		ClassSymbolTable csm = classSymbolTables.get(name);
		if (csm != null){
			return csm;
		}
		else {
			for (ClassSymbolTable cst: classSymbolTables.values()){
				csm = cst.getClassSymbolTable(name);
				if (csm != null) {
					return csm;
				}
			}
		}
		return null;
	}
	
	public void addClass(ICClass c) throws SemanticError{
		classSymbols.put(c.getName(), new ClassSymbol(c));
	}

	
	public void addClassSymbolTable(ClassSymbolTable cst){
		classSymbolTables.put(cst.getMySymbol().getName(), cst);
	}
	
	public String toString(){
		String str = "Global Symbol Table: "+icFileName;
		
		// print list of classes
		for(ClassSymbol cs: classSymbols.values()){
			str += "\n\tClass: "+cs.getName();
		}
		
		// print list of children tables
		if(!classSymbolTables.isEmpty()){
			str += "\nChildren tables: ";
			for(ClassSymbolTable cst: classSymbolTables.values()){
				str += cst.getMySymbol().getName()+", ";				
			}
			str = str.substring(0, str.length()-2);
		}
		str += "\n\n";
		
		// recursively print symbol tables
		for(ClassSymbolTable cst: classSymbolTables.values()){
			str += cst;
		}
		
		return str;
	}
	
	private String icFileName;	
	private Map<String,ClassSymbol> classSymbols;
	private Map<String,ClassSymbolTable> classSymbolTables;

}
